//
//  SMTPMailDelivery.h
//  MailDelivery
//
//  Created by Dante Palacios on 30/08/09.
//  Copyright 2009 Dante Palacios. All rights reserved.
//

/*!
 @header SMTPMailDelivery.h
 @abstract The methods listed here may disappear or change their names without prior notice. For more information, contact palacios.dante\@gmail.com.
*/

#import <Foundation/Foundation.h>
#import <MailDelivery/Constants.h>

@class NSImage;
@class TCPConnection;
@class Message;

/*!
 @class SMTPMailDelivery
 @abstract Class to send emails
 @discussion SMTPMailDelivery class it is a bridge between the <tt>TCPConnection</tt> and <tt>Message</tt> classes, useful to manage the settings of email accounts. By default every message is sent through an instance of <tt>SMTPMailDelivery</tt>, but is not really required, in fact, the only class you need to send emails is <tt>TCPConnection</tt>.
 */

@interface SMTPMailDelivery : NSObject {
@private;
	TCPConnection *_connection;
	NSDictionary *_deliveryAccount;
	BOOL _userCanceled;
}

/*!
 @method initWithDeliveryAccount:
 @abstract .
 @param account
 account used to send emails.
 */

- (id)initWithDeliveryAccount:(NSDictionary *)account;

/*!
 @method deliverMessage:error:
 @abstract tries to send a message.
 @param message
 the message to send.
 @param error
 output error or nil.
 */

- (BOOL)deliverMessage:(Message *)message error:(NSError **)error;

/*!
 @method cancel
 @abstract cancels the message delivery.
 */

- (void)cancel;

/*!
 @method verifyDeliveryAccountAndReturnError:
 @abstract .
 @param error
 output error or nil.
 */

- (BOOL)verifyDeliveryAccountAndReturnError:(NSError **)error;

/*!
 @method deliveryAccountForEmailAddress:
 @abstract Searchs for an account witch contains the specified email.
 @discussion Used by <tt>SMTPMailDelivery</tt> class (in order to mantain the simplicity of the class) when no <tt>deliveryAccount</tt> was specified, this method tries to locate a SMTP account that matches the given email see @link deliveryAccount deliveryAccount @/link.
 @param emailAddress
 an email.
 */

+ (NSDictionary *)deliveryAccountForEmailAddress:(NSString *)emailAddress;

/*!
 @method deliveryAccounts
 @abstract an array of dictionaries representing each of the SMTP accounts of your app.
 @discussion The first time invokes <tt>mailAppDeliveryAccounts</tt> class method importing every delivery account in Mail.app, from there have the same effect that [[NSUserDefaults standardUserDefaults] arrayForKey:@"SMTPAccounts"].
 */

+ (NSArray *)deliveryAccounts;

/*!
 @method genericEmailAccountIconImage
 @abstract A generic email account icon.
 */

+ (NSImage *)genericEmailAccountIconImage;

/*!
 @method mailAppDeliveryAccounts
 @abstract an array of dictionaries representing each of the SMTP accounts in Mail.app.
 */

+ (NSArray *)mailAppDeliveryAccounts;

/*!
 @property connection
 @abstract the <tt>TCPConnection</tt>.
 */

@property (retain) TCPConnection *connection;

/*!
 @property deliveryAccount
 @abstract account used to deliver emails.
 @discussion A <tt>deliveryAccount</tt> is vital, if no account is specified then the instance will try to use Apple Mail's SMTP accounts. If Mail have not been configured, then for every email address in current user's Address Book, it will try to find an entry in Keychain (most of the time we will need a password), a list of servers will be created based on the email address @link //maildelivery_ref/occ/data/MessageAddressee/hostName hostName @/link. If no Keychain entry was found then, it will try to send the message without password. At this point, a <tt>deliveryAccount</tt> have been created using the email address as model. It's strongly recomended that you provide a <tt>deliveryAccount</tt>.
 */

@property (retain) NSDictionary *deliveryAccount;

@end

/*!
 @category SMTPMailDelivery(SMTPMailDeliveryStandardAdditions) 
 @abstract .
 */

@interface SMTPMailDelivery(SMTPMailDeliveryStandardAdditions) 

/*!
 @method deliverMessage:headers:format:error:
 @discussion Deliver an email message.
 @param messageBody
 the contents of the message. If message format is diferent from <tt><i>kMultipartAlternativeMessageFormat</i></tt> any rich text or attachments will be lost.
 @param messageHeaders
 contains all of the values that will appear in the message header.
 @param messageFormat
 the format of the message. Can be <tt><i>kPlainTextMessageFormat</i></tt>, <tt><i>kHTMLMessageFormat</i></tt> or <tt><i>kMultipartAlternativeMessageFormat</i></tt>. 
 @param error
 If no error is required, you may pass 'nil' for the error.
 @result <tt>YES</tt> if the message was sent.
 */

+ (BOOL)deliverMessage:(NSAttributedString *)messageBody headers:(NSDictionary *)messageHeaders format:(NSString *)messageFormat error:(NSError **)error;

/*!
 @method deliverMessage:subject:to:error:
 @discussion Deliver a plain text email message. As in @link deliverMessage:headers:format:error: deliverMessage:headers:format:error: @/link class method passing kPlainTextMessageFormat as message format and a <tt>NSDictionary</tt> containing containing minimal headers to send the message.
 @see deliverMessage:headers:format:error:
 */

+ (BOOL)deliverMessage:(NSString *)messageBody subject:(NSString *)messageSubject to:(NSString *)destinationAddress error:(NSError **)error;

@end

// Notifications

extern NSString *const MailDeliveryCompletedNotification;
extern NSString *const MailDeliveryFailedNotification;

/*!
 @category NSObject(MailDeliveryNotifications)
 @abstract Nofitications sent by <tt>SMTPMailDelivery</tt>.
 */

@interface NSObject(MailDeliveryNotifications)

/*!
 @method mailDeliveryCompleted:
 @abstract the message was sent.
 @param notification
  <tt>NSNotification</tt> <tt>userInfo</tt> contains the message sent as the value for the key \@"message".
 */

- (void)mailDeliveryCompleted:(NSNotification *)notification;

/*!
 @method mailDeliveryFailed:
 @abstract mail delivery failed.
 @discussion notification object is an instance of <tt>SMTPMailDelivery</tt>, if you want to know the reason of the failure, you can do this by getting the error of the <tt>connection</tt> (<tt>TCPConnection</tt>).
 @param notification
 <tt>NSNotification</tt> <tt>userInfo</tt> contains the message the could not be sent as the value for the key \@"message".
 */

- (void)mailDeliveryFailed:(NSNotification *)notification;

@end
